import matplotlib.pyplot as plt
import numpy as np

def create_coordinate_system(x_range=(-10, 10), y_range=(-10, 10), figsize=(10, 8)):
    """
    创建自定义范围的坐标系
    
    参数:
    x_range: x轴范围，默认为(-10, 10)
    y_range: y轴范围，默认为(-10, 10)
    figsize: 图形大小，默认为(10, 8)
    
    返回:
    fig, ax: matplotlib的图形和坐标轴对象
    """
    # 创建图形和坐标轴
    fig, ax = plt.subplots(figsize=figsize)
    
    # 设置坐标轴范围
    x_min, x_max = x_range
    y_min, y_max = y_range
    ax.set_xlim(x_min, x_max)
    ax.set_ylim(y_min, y_max)
    
    # 移除顶部和右侧边框
    spines = ['top', 'right', 'bottom', 'left']
    for spine in spines:
        ax.spines[spine].set_visible(False)
    
    # 隐藏默认的刻度标记
    ax.set_xticks([])
    ax.set_yticks([])    
    
    # 绘制坐标轴
    ax.axhline(y=0, color='black', linewidth=1.2)  # x轴
    ax.axvline(x=0, color='black', linewidth=1.2)  # y轴
    
    # 添加箭头指示坐标轴方向
    ax.annotate('', xy=(x_max, 0), xytext=(0, 0),
                arrowprops=dict(arrowstyle="->", lw=1.2, color='black'))
    ax.annotate('', xy=(0, y_max), xytext=(0, 0),
                arrowprops=dict(arrowstyle="->", lw=1.2, color='black'))
    
    # 设置坐标标签
    # 计算合适的刻度间隔
    x_interval = max(1, (x_max - x_min) // 20)
    y_interval = max(1, (y_max - y_min) // 20)

     # 标记原点O
    ax.text(-x_interval/5, -y_interval/5, 'O', fontsize=14, fontweight='bold', color='red')
    
    # 绘制x轴刻度
    for i in range(int(x_min), int(x_max), x_interval):
        if i == 0:
            continue
        ax.plot([i, i], [0, 0.02 * (y_max - y_min)], 'black', linewidth=1.5, linestyle='-')
        ax.text(i, -0.5, i, fontsize=10, ha='center')
    
    # 绘制y轴刻度
    for i in range(int(y_min), int(y_max), y_interval):
        if i == 0:
            continue
        ax.plot([0, 0.02 * (x_max - x_min)], [i, i], 'black', linewidth=1.5, linestyle='-')
        ax.text(-0.5, i, i, fontsize=10, ha='center', va='center')
    
    # 设置坐标轴标签
    ax.text(x_max * 0.95, -0.5, 'x', fontsize=12, fontweight='bold')
    ax.text(-0.5, y_max * 0.95, 'y', fontsize=12, fontweight='bold')
    
    # 调整布局
    plt.tight_layout()
    
    return fig, ax

# 测试函数
if __name__ == "__main__":
    # 示例1: 默认范围
    fig1, ax1 = create_coordinate_system()
    # 在坐标系上添加一条直线 y = 2x + 1
    x = np.linspace(-5, 5, 100)
    y = 2*x + 1
    ax1.plot(x, y, 'b-', linewidth=2, label='y = 2x + 1')
    ax1.legend()
    plt.show()
    
    # 示例2: 自定义范围
    fig2, ax2 = create_coordinate_system(x_range=(-5, 5), y_range=(-3, 3), figsize=(8, 6))
    # 添加一个二次函数 y = x^2
    x2 = np.linspace(-3, 3, 100)
    y2 = x2**2
    ax2.plot(x2, y2, 'r-', linewidth=2, label='y = x²')
    ax2.legend()
    plt.show()
    
    # 示例3: 更大的范围
    fig3, ax3 = create_coordinate_system(x_range=(-20, 20), y_range=(-15, 15))
    # 添加正弦函数
    x3 = np.linspace(-20, 20, 200)
    y3 = 5 * np.sin(x3)
    ax3.plot(x3, y3, 'g-', linewidth=2, label='y = 5sin(x)')
    ax3.legend()
    plt.show()
